<template>
  <div class="emoji-textarea-wrapper">
    <textarea
      v-model="localValue"
      class="emoji-textarea"
      :class="{ minimal }"
      :placeholder="placeholder"
      :rows="rows"
      :maxlength="maxlength"
      @input="handleInput"
      @keydown="handleKeyDown"
      ref="textareaRef"
    ></textarea>
    
    <div class="textarea-footer"
      v-if="showFooter || showEmojiButton || showCounter"
    >
      <div class="textarea-left"
        v-if="$slots.left"
      >
        <slot name="left"></slot>
      </div>
      
      <div class="textarea-right"
        v-if="showEmojiButton || showCounter"
      >
        <div class="char-counter"
          v-if="showCounter && maxlength"
          :class="{ 'near-limit': localValue.length > maxlength * 0.9 }"
        >
          {{ localValue.length }}/{{ maxlength }}
        </div>
        <button
          class="emoji-button"
          :class="{ active: showEmojiPicker }"
          @click="toggleEmojiPicker"
          v-if="showEmojiButton"
          type="button"
          aria-label="表情选择器"
        >
          😊
        </button>
      </div>
    </div>
    
    <div class="emoji-picker-container" ref="pickerContainerRef"
      v-if="showEmojiButton"
    >
      <EmojiPicker
        :visible="showEmojiPicker"
        @select="handleEmojiSelect"
        @close="closeEmojiPicker"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
import EmojiPicker from './EmojiPicker.vue'

// Props
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  placeholder: {
    type: String,
    default: '请输入内容...'
  },
  rows: {
    type: Number,
    default: 3
  },
  maxlength: {
    type: Number,
    default: 0
  },
  showEmojiButton: {
    type: Boolean,
    default: true
  },
  showCounter: {
    type: Boolean,
    default: false
  },
  showFooter: {
    type: Boolean,
    default: true
  },
  minimal: {
    type: Boolean,
    default: false
  }
})

// Emits
const emit = defineEmits<{
  (e: 'update:modelValue', value: string): void
  (e: 'input', event: Event): void
  (e: 'focus', event: Event): void
  (e: 'blur', event: Event): void
  (e: 'keydown', event: KeyboardEvent): void
  (e: 'emoji-select', emoji: string): void
}>()

// Refs
const textareaRef = ref<HTMLTextAreaElement | null>(null)
const pickerContainerRef = ref<HTMLDivElement | null>(null)
const showEmojiPicker = ref(false)

// 本地值
const localValue = computed({
  get: () => props.modelValue,
  set: (value) => {
    if (props.maxlength && value.length > props.maxlength) {
      return
    }
    emit('update:modelValue', value)
  }
})

// 处理输入
const handleInput = (event: Event) => {
  emit('input', event)
}

// 处理按键事件
const handleKeyDown = (event: KeyboardEvent) => {
  emit('keydown', event)
  
  // ESC键关闭表情选择器
  if (event.key === 'Escape') {
    closeEmojiPicker()
  }
}

// 切换表情选择器显示状态
const toggleEmojiPicker = () => {
  showEmojiPicker.value = !showEmojiPicker.value
  
  if (showEmojiPicker.value) {
    nextTick(() => {
      // 确保选择器在视图中正确定位
      adjustPickerPosition()
    })
  }
}

// 关闭表情选择器
const closeEmojiPicker = () => {
  showEmojiPicker.value = false
}

// 处理表情选择
const handleEmojiSelect = (emoji: string) => {
  if (!textareaRef.value) return
  
  const textarea = textareaRef.value
  const start = textarea.selectionStart
  const end = textarea.selectionEnd
  const text = localValue.value
  
  // 计算插入表情后的新文本
  let newText = text.substring(0, start) + emoji + text.substring(end)
  
  // 检查是否超出最大长度限制
  if (props.maxlength && newText.length > props.maxlength) {
    return
  }
  
  // 更新文本
  localValue.value = newText
  
  // 触发emoji-select事件
  emit('emoji-select', emoji)
  
  // 重新聚焦到文本框并设置光标位置
  nextTick(() => {
    if (textareaRef.value) {
      textareaRef.value.focus()
      const newPosition = start + emoji.length
      textareaRef.value.selectionStart = newPosition
      textareaRef.value.selectionEnd = newPosition
    }
  })
}

// 调整表情选择器位置
const adjustPickerPosition = () => {
  if (!pickerContainerRef.value || !textareaRef.value) return
  
  const pickerContainer = pickerContainerRef.value
  const textarea = textareaRef.value
  const textareaRect = textarea.getBoundingClientRect()
  
  // 默认在输入框下方
  let positionClass = 'position-bottom'
  
  // 计算视口高度和输入框位置，判断是否需要放在上方
  const viewportHeight = window.innerHeight
  const pickerHeight = 360 // 预估表情选择器高度
  
  if (viewportHeight - textareaRect.bottom < pickerHeight) {
    positionClass = 'position-top'
  }
  
  // 移除所有位置类
  pickerContainer.classList.remove('position-top', 'position-bottom')
  // 添加新位置类
  pickerContainer.classList.add(positionClass)
}

// 点击外部关闭表情选择器
const handleClickOutside = (event: MouseEvent) => {
  if (!pickerContainerRef.value || !textareaRef.value) return
  
  const pickerContainer = pickerContainerRef.value
  const textarea = textareaRef.value
  const emojiButton = textarea.nextElementSibling?.querySelector('.emoji-button') as HTMLButtonElement
  
  // 如果点击的不是表情选择器、文本框或表情按钮，则关闭选择器
  if (showEmojiPicker.value && 
      !pickerContainer.contains(event.target as Node) && 
      event.target !== textarea && 
      (!emojiButton || event.target !== emojiButton)) {
    closeEmojiPicker()
  }
}

// 监听窗口大小变化，调整选择器位置
const handleResize = () => {
  if (showEmojiPicker.value) {
    adjustPickerPosition()
  }
}

// 生命周期钩子
onMounted(() => {
  document.addEventListener('click', handleClickOutside)
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
  window.removeEventListener('resize', handleResize)
})

// 暴露方法给父组件
defineExpose({
  focus: () => {
    textareaRef.value?.focus()
  },
  blur: () => {
    textareaRef.value?.blur()
  },
  toggleEmojiPicker,
  closeEmojiPicker,
  insertEmoji: handleEmojiSelect
})
</script>

<style scoped>
.emoji-textarea-wrapper {
  position: relative;
  width: 100%;
}

.emoji-textarea {
  width: 100%;
  min-height: 60px;
  padding: 12px;
  border: 1px solid #ddd;
  border-radius: 8px;
  font-size: 14px;
  font-family: inherit;
  line-height: 1.5;
  resize: vertical;
  transition: border-color 0.3s, box-shadow 0.3s;
  box-sizing: border-box;
}

.emoji-textarea:focus {
  outline: none;
  border-color: #42b983;
  box-shadow: 0 0 0 2px rgba(66, 185, 131, 0.2);
}

.emoji-textarea::placeholder {
  color: #999;
}

.emoji-textarea.minimal {
  border: none;
  background: transparent;
  outline: none;
  font-size: 16px;
  line-height: 1.6;
  color: #333;
  resize: none;
  padding: 0;
}

.emoji-textarea.minimal:focus {
  outline: none;
  border: none;
  box-shadow: none;
}

.textarea-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 8px;
  padding: 0 4px;
}

.textarea-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.textarea-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.char-counter {
  font-size: 12px;
  color: #999;
  font-family: monospace;
}

.char-counter.near-limit {
  color: #ff6b6b;
}

.emoji-button {
  width: 32px;
  height: 32px;
  border: 1px solid #ddd;
  border-radius: 6px;
  background: white;
  font-size: 18px;
  cursor: pointer;
  transition: all 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.emoji-button:hover {
  border-color: #42b983;
  background-color: #f0fff4;
}

.emoji-button.active {
  border-color: #42b983;
  background-color: #e8f5e9;
  color: #42b983;
}

.emoji-button:active {
  transform: scale(0.95);
}

.emoji-picker-container {
  position: absolute;
  z-index: 1000;
}

.emoji-picker-container.position-bottom {
  top: 100%;
  right: 0;
  margin-top: 4px;
}

.emoji-picker-container.position-top {
  bottom: 100%;
  right: 0;
  margin-bottom: 4px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .emoji-textarea {
    font-size: 16px; /* 防止iOS自动缩放 */
  }
  
  .emoji-button {
    width: 36px;
    height: 36px;
    font-size: 20px;
  }
  
  .textarea-footer {
    flex-wrap: wrap;
    gap: 8px;
  }
}

@media (max-width: 480px) {
  .emoji-textarea {
    padding: 10px;
    min-height: 50px;
  }
  
  .textarea-right {
    gap: 8px;
  }
}
</style>
